# GodJin/model/browser.py
import os
import atexit
import threading
from typing import Optional
from playwright.sync_api import sync_playwright
# PLAYWRIGHT_HEADLESS = 1
class DouyinBrowser:
    """懒加载 + 全局单例 + 自动自愈"""
    _instance: Optional["DouyinBrowser"] = None
    _glock = threading.Lock()

    def __init__(self):
        # 不在 __init__ 里启动浏览器，延后到第一次使用
        self._lock = threading.Lock()
        self._pw = None
        self._browser = None
        self._context = None

        # 环境变量控制
        # PLAYWRIGHT_HEADLESS: "1"/"true" => 无头；"0"/"false" => 有头（仅本地调试）
        hv = os.environ.get("PLAYWRIGHT_HEADLESS", "1").lower()
        self._headless = hv in ("", "1", "true", "yes", "on")
        # self._headless = False
        self._proxy = os.environ.get("PLAYWRIGHT_PROXY", "").strip()  # 例: http://127.0.0.1:7890

        # 进程退出时清理
        atexit.register(self.close)

    @classmethod
    def instance(cls) -> "DouyinBrowser":
        if cls._instance is not None:
            return cls._instance
        with cls._glock:
            if cls._instance is None:
                cls._instance = cls()
        return cls._instance

    def _ensure_started(self):
        """确保 playwright/browser/context 已经就绪；若崩溃则重建。"""
        with self._lock:
            # 已就绪就探活一次
            if self._context:
                try:
                    p = self._context.new_page()
                    p.close()
                    return
                except Exception:
                    # 探活失败，走重建
                    self._safe_close()

            print("[INIT] 启动 Playwright 浏览器...")
            if not self._pw:
                self._pw = sync_playwright().start()
# 头
            launch_kwargs = {"headless": False}


            # if self._proxy:
            #     launch_kwargs["proxy"] = {"server": self._proxy}
            #     print(f"[INIT] 使用代理: {self._proxy}")

            self._browser = self._pw.chromium.launch(**launch_kwargs)
            self._context = self._browser.new_context(
                # user_agent=("Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
                #             "AppleWebKit/537.36 (KHTML, like Gecko) "
                #             "Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0"),
                # locale="zh-CN",
                # timezone_id="Asia/Shanghai",
                # viewport={"width": 1366, "height": 768},
            )

            # 2) 追加请求头 —— 关键是 UA-CH 族
            # self._context.set_extra_http_headers({
            #     "Accept-Language": "zh-CN,zh;q=0.9",
            #     "Referer": "https://www.douyin.com/",
            #     "sec-ch-ua": '"Chromium";v="114", "Microsoft Edge";v="114", "Not;A=Brand";v="24"',
            #     "sec-ch-ua-mobile": "?0",
            #     "sec-ch-ua-platform": '"Windows"',
            #     "sec-ch-ua-full-version-list": (
            #         '"Chromium";v="114.0.0.0", "Microsoft Edge";v="114.0.1823.82", "Not;A=Brand";v="24.0.0.0"'
            #     ),
            # })

            # 3) 伪装 JS 环境：去掉 webdriver，补 userAgentData
            # self._context.add_init_script("""
            #   // webdriver -> undefined
            #   Object.defineProperty(navigator, 'webdriver', { get: () => undefined });
            #
            #   // 补 userAgentData（UA-CH 的 JS 侧）
            #   try {
            #     const brands = [
            #       { brand: "Chromium", version: "114" },
            #       { brand: "Microsoft Edge", version: "114" },
            #       { brand: "Not A(Brand", version: "24" }
            #     ];
            #     Object.defineProperty(navigator, 'userAgentData', {
            #       get: () => ({ brands, mobile: false, platform: "Windows" })
            #     });
            #   } catch(e) {}
            #
            #   // 可选：简单 patch 一些常见指纹（不做太重）
            #   Object.defineProperty(navigator, 'platform', { get: () => "Win32" });
            # """)




            self._context.set_default_timeout(15000)
            page = self._context.new_page()
            # 4) 页面级别也加一层（双保险）
            # page = self._context.new_page()
            # page.add_init_script("""
            #   Object.defineProperty(navigator, 'webdriver', { get: () => undefined });
            # """)
            page.goto("https://www.douyin.com/")

            # 在 DouyinBrowser 类里加上这段（位置不限，类体内即可）

    @property
    def browser(self):
        """兼容旧代码：需要时才启动并返回 browser。"""
        self._ensure_started()
        return self._browser

    @property
    def context(self):
        """兼容旧代码：需要时才启动并返回 context。"""
        self._ensure_started()
        return self._context

    def _safe_close(self):
        """内部关闭，不抛异常。"""
        try:
            if self._context:
                self._context.close()
        except Exception:
            pass
        try:
            if self._browser:
                self._browser.close()
        except Exception:
            pass
        self._context = None
        self._browser = None

    def close(self):
        """供 atexit/外部调用的整体关闭。"""
        try:
            self._safe_close()
        finally:
            try:
                if self._pw:
                    self._pw.stop()
            except Exception:
                pass
            self._pw = None

    # ===== 你原有的调用方式仍然可用 =====
    def new_page(self):
        """和你现有代码兼容：返回一个可用的新 Page（记得用完 page.close()）"""
        self._ensure_started()
        page = self._context.new_page()
        page.set_default_timeout(15000)

        # 基本伪装（和你之前相同逻辑）
        # page.add_init_script("""
        #     Object.defineProperty(navigator, 'webdriver', { get: () => undefined });
        #     window.chrome = window.chrome || {};
        #     try {
        #       Object.defineProperty(navigator, 'userAgentData', {
        #         get: () => ({ brands: [{brand:'Chromium', version:'140'}, {brand:'Microsoft Edge', version:'140'}],
        #                        mobile: false, platform: 'Windows' })
        #       });
        #     } catch (e) {}
        # """)
        return page




# 暴露一个“全局单例”实例（但不会立刻启动浏览器）
douyin_browser = DouyinBrowser.instance()
#
# with sync_playwright() as p:
#     launch_args = [
#         "--disable-blink-features=AutomationControlled",
#         "--no-sandbox",
#         "--disable-dev-shm-usage",
#     ]
#
#     browser = p.chromium.launch(headless=False, args=launch_args)
#
#     context = browser.new_context(
#         user_agent=("Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
#                     "AppleWebKit/537.36 (KHTML, like Gecko) "
#                     "Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0"),
#         locale="zh-CN",
#         timezone_id="Asia/Shanghai",
#         viewport={"width": 1366, "height": 768},
#         proxy={"server": proxy} if proxy else None,  # 🔥 支持代理
#     )
#
#
#     )